import axios from 'axios'
import { MessageBox } from 'element-ui'
import router from '../router'

const request = axios.create({
  // 表示请求超过时间
  timeout: 20000
})

// 请求拦截
request.interceptors.request.use(config => {
  config.headers['Content-Type'] = 'application/json;charset=utf-8'
  const token = localStorage.getItem('access-token')
  const refreshToken = localStorage.getItem('refresh-token')
  // 接口设置token
  if (token) {
    config.headers['X-Access-Token'] = token
    config.headers['X-Refresh-Token'] = refreshToken
  }
  return config
}, error => {
  return Promise.reject(error)
})

// 创建一个变量来保存正在刷新token的Promise
let refreshTokenPromise = null

// 响应拦截
request.interceptors.response.use(
  async response => {
    // console.log(response)
    let res = response.data

    // 如果JWT不通过，提示用户返回登录
    if (res.code === '401') {
      console.log(401)
      const refreshToken = localStorage.getItem('refresh-token')
      if (!refreshToken) {
        redirectLogin()
        return res
      }

      // 如果已经有一个刷新token的Promise在进行中，就等待它完成
      if (!refreshTokenPromise) {
        console.log('正在刷新token中...')
        refreshTokenPromise = refreshTokenPromiseFunc()
      }

      // 等待刷新token完成后，再继续之前的请求
      return refreshTokenPromise.then(res => {
        console.log(res)
        // 使用新的accessToken重新发送之前的请求
        return request(response.config)
      }).catch(err => {
        console.error(err)
        redirectLogin()
        return res
      }).finally(() => {
        refreshTokenPromise = null
      })
    } else {
      console.log('reach else')
      console.log(response)
      // 如果是返回的文件
      if (response.config.data) {
        let data = JSON.parse(response.config.data)
        if (data.responseType === 'blob') {
          return res
        }
      }

      // 兼容服务端返回的字符串数据
      if (typeof res === 'string') {
        res = res ? JSON.parse(res) : res
      }
      return res
    }
  }, error => {
    console.error('err=========' + error)
    return Promise.reject(error)
  }
)

function redirectLogin () {
  MessageBox.confirm('登录信息已过期，请重新登陆', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '返回',
    customClass: 'message-confirm',
    type: 'warning'
  }).then(() => {
    router.push('/Login')
    localStorage.clear()
  }).catch(() => {
    console.log('登录信息已过期，用户取消弹框')
  })
}

// 刷新Token
function refreshTokenPromiseFunc () {
  return get('/common/auth/refreshToken', {refreshToken: localStorage.getItem('refresh-token')})
    .then((res) => {
      if (res && res.code === '200' && res.result['accessToken'] && res.result['refreshToken']) {
        localStorage.setItem('access-token', res.result['accessToken'])
        localStorage.setItem('refresh-token', res.result['refreshToken'])
        return res.result['accessToken']
      }
      throw new Error('刷新token失败')
    })
}

// 封装get请求 axios.get(url, {params: params})
export const get = (url, params) => request.get(url, { params })
// 封装post请求 axios.post(url, {name: '阿边', age: 23})
export const post = (url, data) => request.post(url, data)
// 封装删除接口
export const del = (url, data) => request.delete(url, data)
// 封装删除接口
export const del2 = (url, params) => request.delete(url, { params })
// 封装修改接口
export const put = (url, data) => request.put(url, data)
// 封装导出接口
export const exportDefault = (url, data) => axios.post(url, data, {
  responseType: 'blob',
  headers: {
    token: localStorage.getItem('access-token') ? localStorage.getItem('access-token') : ''
  }
})

export default request
